//#include <system.h>

#include "monitor.h"

//***************************************************************************
//  String definitions for prompts and messages
//***************************************************************************
#define MAX_RESPONSE_LEN 4


char pResponse[] = {
// SCS Prompts
  Resp_Prompt_OK, 2, '>',0x0d,
  Resp_Prompt_UE, 2, 'E',0x0d,
//  Resp_Prompt_LE, 2, 'e',0x0d,                 //

  Resp_Prompt_ND, 3, 'N','D',0x0d,
//  Resp_Prompt_CF, 3, 'C','F',0x0d,             //
//  Resp_Prompt_BC, 3, 'B','C',0x0d,             //
  Resp_Prompt_DF, 3, 'D','F',0x0d,
  Resp_Prompt_FI, 3, 'F','I',0x0d,
  Resp_Prompt_RO, 3, 'R','O',0x0d,
  Resp_Prompt_FO, 3, 'F','O',0x0d,
//  Resp_Prompt_NE, 3, 'N','E',0x0d,             //
//  Resp_Prompt_FN, 3, 'F','N',0x0d,             //
//  Resp_Message_NU, 3, 'N','U',0x0d,            //

  Resp_Message_DD1, 4, 'D','D','1',0x0d,
//  Resp_Message_DD2, 4, 'D','D','2',0x0d,       //
  Resp_Message_DR1, 4, 'D','R','1',0x0d,
//  Resp_Message_DR2, 4, 'D','R','2',0x0d,       //
//  0, 0,                                        //
};


//***************************************************************************
// External Routines
//***************************************************************************

//***************************************************************************
// Name: monSendByte
// Description: Send a single byte to the Vinculum Monitor.
// Parameters: monData - Byte data.
// Returns: None.
// Comments:
//***************************************************************************
void monSendByte(char monData)
{
  monWrite(monData);
}

//***************************************************************************
// Name: monCmdSend
// Description: Send a single byte command to the Vinculum Monitor.
// Parameters: monCmd - Byte code of command.
// Returns: None.
// Comments: Supports only SCS commands without parameters.
//***************************************************************************
void monCmdSend(char monCmd)
{
  if (monCmd != CMD_CR)
  {
    monWrite(monCmd);
  }
  monWrite(0x0d);
}

//***************************************************************************
// Name: monCmdSendByteParam
// Description: Send a single byte command to the Vinculum Monitor with a
//              single byte parameter.
// Parameters: monCmd - Byte code of command.
//             monParam - Byte parameter for command.
// Returns: None.
// Comments: Supports only SCS commands with a single byte parameter.
//***************************************************************************
void monCmdSendByteParam(char monCmd, unsigned char monParam)
{
  monWrite(monCmd);
  monWrite(' ');
  monWrite(monParam);
  monWrite(0x0d);
}

//***************************************************************************
// Name: monCmdSendByteParam
// Description: Send a single byte command to the Vinculum Monitor with a
//              single byte parameter.
// Parameters: monCmd - Byte code of command.
//             monParam - Byte parameter for command.
// Returns: None.
// Comments: Supports only SCS commands with a single byte parameter.
//***************************************************************************
void monCmdSendParam(char monCmd, unsigned char monCount, unsigned char *pmonParam)
{
  monWrite(monCmd);
  if (monCount--)
  {
    monWrite(' ');
    monWrite(*pmonParam++);
    while (monCount--)
    {
     monWrite(*pmonParam++);
    }
  }
  monWrite(0x0d);
}


//***************************************************************************
// Name: monResponse
// Description: Waits for a response from the Vinculum.
// Parameters: None.
// Returns: tpResp - response code from enum vResponse.
// Comments: If no valid response matched or a carriage return detected then
//           returns Resp_None. Always parses to a carriage return.
//***************************************************************************
enum vResponse monResponse() {

enum vResponse tpResp, tpThis;
unsigned char romBufOffset;
char cBuf[MAX_RESPONSE_LEN];
unsigned char bufCnt, romCnt;
char data_in;
unsigned int tpBuf;

// initialise prompt detection
bufCnt = 0;
tpResp = Resp_None;

// read single byte from SPI if one waiting
        
if (monRead(&data_in) != XFER_RETRY)
{
  for (bufCnt = 0; bufCnt < MAX_RESPONSE_LEN; bufCnt++)
  {
    romBufOffset = 0;
    // put last read byte of data in receive/compare buffer
    cBuf[bufCnt] = data_in;
    // find if the Message matches any of our predefined types
    while (tpResp == Resp_None)
    {
      tpThis = pResponse[romBufOffset++];                   // message code for this entry
      romCnt = pResponse[romBufOffset++];                   // number of characters for this entry
      if (romCnt == 0)                                      // reached end of Message definitions
      {
        break;
      }
      if (romCnt == bufCnt + 1)                             // check against this Message if length is correct
      {
        unsigned char j;
        tpResp = tpThis;
        for (j = 0; j < bufCnt; j++)
        {
          romCnt--;
          tpBuf = pResponse[romBufOffset++];
          if (tpBuf != cBuf[j])                             // mis-match of data
          {
            tpResp = Resp_None;
            break;                                          // break from for loop
          }
        }
      }
      else if (romCnt > bufCnt)
      {
        break;                                              // length of reponse too long
      }
      romBufOffset += romCnt;
    }

    if (data_in == 0x0d)
      break;

    if (tpResp != Resp_None)
      break;

    // read subsequent bytes from the SPI interface
    data_in = monReadWait();
    tpResp = Resp_None;
  }

  if (bufCnt == MAX_RESPONSE_LEN)
  {
    // wait for carriage return
    while (data_in != 0x0d)
    {
      data_in = monReadWait();
    }
  }
}

return tpResp;
}

//***************************************************************************
// Name: monPrompt
// Description: Calls monResponse until a prompt is received.
// Parameters: None.
// Returns: tpResp - response code from enum vResponse.
// Comments: Waits for monResponse to return a non-message value which is
//           less than Resp_Prompt_End.
//***************************************************************************
enum vResponse monPrompt()
{
  enum vResponse tpResp;

  do
  {
    tpResp = monResponse();
  } while (tpResp > Resp_Prompt_End);

  return tpResp;
}